package com.agileai.portal.portlets.iframe;

import java.io.IOException;
import java.io.StringWriter;
import java.security.Principal;
import java.util.HashMap;
import java.util.Locale;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.ProcessAction;
import javax.portlet.ReadOnlyException;
import javax.portlet.RenderRequest;
import javax.portlet.ValidatorException;
import javax.servlet.http.HttpSession;

import org.mvel2.templates.TemplateRuntime;

import com.agileai.hotweb.common.StringTemplateLoader;
import com.agileai.portal.driver.GenericPotboyPortlet;
import com.agileai.portal.driver.common.PortletRequestHelper;
import com.agileai.portal.driver.model.Theme;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;

public class IframePortlet extends GenericPotboyPortlet {

	private String defaultIframeSrc = "";
	private String defaultWidth = "";
	private String defaultHeight = "";
	private String defaultScroll = "";
	private String defaultPxOrPercent = "";
	private String defaultXStart = "";
	private String defaultYStart = "";
	private String defaultXEnd = "";
	private String defaultYEnd = "";
	private String defaultAutoExend = "false";

	public void init(PortletConfig config) throws PortletException {
		super.init(config);

		this.defaultIframeSrc = config.getInitParameter("DefaultIframeSrc");
		this.defaultWidth = config.getInitParameter("DefaultWidth");
		this.defaultHeight = config.getInitParameter("DefaultHeight");
		this.defaultScroll = config.getInitParameter("DefaultScroll");
		this.defaultAutoExend = config.getInitParameter("DefaultAutoExtend");

		this.defaultPxOrPercent = config.getInitParameter("DefaultPxOrPercent");
		this.defaultXStart = "0px";
		this.defaultYStart = "0px";
		this.defaultXEnd = this.defaultWidth;
		this.defaultYEnd = this.defaultHeight;
	}

	@SuppressWarnings("rawtypes")
	public void prepareView(RenderRequest request) {
		PortletPreferences preferences = request.getPreferences();
		String iframeSrc = preferences.getValue("DefaultIframeSrc", this.defaultIframeSrc);
		String iframeWidth = preferences.getValue("DefaultWidth", this.defaultWidth);
		String iframeHeight = preferences.getValue("DefaultHeight", this.defaultHeight);
		String iframeScroll = preferences.getValue("DefaultScroll", this.defaultScroll);
		String iframePxOrPercent = preferences.getValue("DefaultPxOrPercent", this.defaultPxOrPercent);
		String iframeXStart = preferences.getValue("DefaultXStart", this.defaultXStart);
		String iframeYStart = preferences.getValue("DefaultYStart", this.defaultYStart);
		String iframeXEnd = preferences.getValue("DefaultXEnd", this.defaultXEnd);
		String iframeYEnd = preferences.getValue("DefaultYEnd", this.defaultYEnd);
		String iframeAutoExtend = preferences.getValue("DefaultAutoExtend", this.defaultAutoExend);
		
		if ((!iframeWidth.contains("%")) && (!iframeWidth.contains("px"))) {
			if ("%".equals(iframePxOrPercent))
				request.setAttribute("width", iframeWidth + "%");
			else
				request.setAttribute("width", iframeWidth + "px");
		} else {
			request.setAttribute("width", iframeWidth);
		}
		if (!iframeHeight.contains("px")){
			if (iframeHeight.indexOf(Theme.ThemeBodyHeight) > -1){
				String template = iframeHeight;
				HashMap vars = this.buildVarMap(request);
				iframeHeight = String.valueOf(TemplateRuntime.eval(template, vars));
			}
			request.setAttribute("height", iframeHeight + "px");
		}
		else {
			request.setAttribute("height", iframeHeight);
		}

		iframeSrc = this.evalFrameURL(iframeSrc,request);
		
		request.setAttribute("src", iframeSrc);
		request.setAttribute("scroll", iframeScroll);
		request.setAttribute("pxOrPercent", iframePxOrPercent);
		request.setAttribute("xStart", iframeXStart);
		request.setAttribute("yStart", iframeYStart);
		request.setAttribute("xEnd", iframeXEnd);
		request.setAttribute("yEnd", iframeYEnd);
		request.setAttribute("autoExtend", iframeAutoExtend);
	}
	
	@SuppressWarnings({"rawtypes", "unchecked" })
	private HashMap buildVarMap(PortletRequest request){
		HashMap result = new HashMap();
		HttpSession portalSession = PortletRequestHelper.getPortalHttpSession(request);
		Theme theme = (Theme)portalSession.getAttribute(Theme.class.getName());
		String height = (String)portalSession.getAttribute(Theme.WindowScreenHeight);
		String outherHeight = theme.getOuterHeight();
		String themeBodyHeight = String.valueOf(Integer.parseInt(height)- Integer.parseInt(outherHeight));
		result.put(Theme.ThemeBodyHeight, themeBodyHeight);
		return result;
	}
	
	private String evalFrameURL(String iframeSrc,PortletRequest request){
		String result = null;
		try {
			StringWriter writer = new StringWriter();
			HashMap<String,String> root = new HashMap<String,String>();
			
			Principal principal = request.getUserPrincipal();
			String currentUserId = principal.getName();
			
			root.put("currentUserId",currentUserId);
			this.tryMergeVars(root, iframeSrc, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
			result = iframeSrc;
		}
		return result;
	}
	
	public void tryMergeVars(HashMap<String,String> root,String template,StringWriter writer) throws Exception {
		String encoding = "utf-8";
    	Configuration cfg = new Configuration();
    	cfg.setTemplateLoader(new StringTemplateLoader(template));  
    	cfg.setEncoding(Locale.getDefault(), encoding);
        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
    	Template temp = cfg.getTemplate("");
    	temp.setEncoding(encoding);
        temp.process(root, writer);
        writer.flush();
	}
	
	public void prepareEdit(RenderRequest request) {

		PortletPreferences preferences = request.getPreferences();
		String iframeSrc = preferences.getValue("DefaultIframeSrc", this.defaultIframeSrc);
		String iframeWidth = preferences.getValue("DefaultWidth", this.defaultWidth);
		String iframeHeight = preferences.getValue("DefaultHeight", this.defaultHeight);
		String iframeScroll = preferences.getValue("DefaultScroll", this.defaultScroll);
		String iframePxOrPercent = preferences.getValue("DefaultPxOrPercent", this.defaultPxOrPercent);
		String iframeAutoExtend = preferences.getValue("DefaultAutoExtend", this.defaultAutoExend);
		
		request.setAttribute("src", iframeSrc);
		request.setAttribute("width", iframeWidth.replace("px", "").replace("%", ""));
		request.setAttribute("height", iframeHeight.replace("px", "").replace("%", ""));
		request.setAttribute("scroll", iframeScroll);
		request.setAttribute("pxOrPercent", iframePxOrPercent);
		request.setAttribute("autoExtend", iframeAutoExtend);
	}

	@ProcessAction(name = "saveIframe")
	public void saveIframe(ActionRequest request, ActionResponse response) throws ReadOnlyException,
			PortletModeException, ValidatorException, IOException {
		String src = request.getParameter("iframeSrc");
		String width = request.getParameter("iframeWidth");
		String height = request.getParameter("iframeHeight");
		String scroll = request.getParameter("scroll");
		String pxOrPercent = request.getParameter("pxOrPercent");
		String autoExtend = request.getParameter("autoExtend");

		PortletPreferences preferences = request.getPreferences();
		preferences.setValue("DefaultIframeSrc", src);
		preferences.setValue("DefaultWidth", width);
		preferences.setValue("DefaultHeight", height);
		preferences.setValue("DefaultYEnd", height);
		preferences.setValue("DefaultPxOrPercent", pxOrPercent);
		preferences.setValue("DefaultAutoExtend", autoExtend);

		if (!StringUtil.isNullOrEmpty(scroll)) {
			scroll = "true".equalsIgnoreCase(scroll) ? "auto" : "no";
		} else {
			scroll = "no";
		}
		preferences.setValue("DefaultScroll", scroll);
		preferences.store();
		response.setPortletMode(PortletMode.VIEW);
	}

	@ProcessAction(name = "cancelChangeIframe")
	public void cancelChangeIframe(ActionRequest request, ActionResponse response) throws ReadOnlyException,
			PortletModeException, ValidatorException, IOException {
		response.setPortletMode(PortletMode.VIEW);
	}

	@ProcessAction(name = "resetChangeIframe")
	public void resetChangeIframe(ActionRequest request, ActionResponse response) throws ReadOnlyException,
			PortletModeException, ValidatorException, IOException {
		PortletPreferences preferences = request.getPreferences();
		preferences.setValue("DefaultIframeSrc", this.defaultIframeSrc);
		preferences.setValue("DefaultWidth", this.defaultWidth);
		preferences.setValue("DefaultHeight", this.defaultHeight);
		preferences.setValue("DefaultScroll", this.defaultScroll);
		preferences.setValue("DefaultPxOrPercent", this.defaultPxOrPercent);
		preferences.setValue("DefaultXStart", this.defaultXStart);
		preferences.setValue("DefaultYStart", this.defaultYStart);
		preferences.setValue("DefaultXEnd", this.defaultXEnd);
		preferences.setValue("DefaultYEnd", this.defaultYEnd);
		preferences.setValue("DefaultAutoExtend", this.defaultAutoExend);
		
		preferences.store();
		response.setPortletMode(PortletMode.VIEW);
	}
}